/*C语言标准头文件*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>

#include "_typedef.h"
#include "parse_ts.h"
#include "common.h"


#define PARSE_DEBUG 1

//打开文件
static int TS_iFileOpen(char* n8FileName)
{
    int fd = open(n8FileName, O_CREAT | O_RDWR , S_IRUSR | S_IWUSR);
    if(-1 == fd)
    {
        printf("文件打开失败...\n");
        return FILE_OPEN_ERR;
    }
    return fd;
}

//读取文件
static CSTS_Error_Code TS_iFileRead(int fd, u8 *u8Buffer, int* BufferLen)
{
    int nReadLen = 0;
    if (-1 == fd || NULL == u8Buffer || 0 >= BufferLen)
    {
        //参数错误
        return CSTS_ERROR_BAD_PARAMETER;
    }

    //判断文件指针是否可以移动，即判断可读性
    if (lseek(fd, 0, SEEK_CUR) == -1)
    {
        printf("该文件不能被读取...22\n");
        return CSTS_ERROR_FILE_SEEK_ERROR;
    }

    //判断文件是否读取成功
    if (-1 == (nReadLen = read(fd, u8Buffer, *BufferLen)))
    {
        printf("读取文件失败...44\n");
        return CSTS_ERROR_FILE_READ_ERROR;
    }

    if(nReadLen < *BufferLen)
    {
        *BufferLen = nReadLen;
    }

    return CSTS_SUCCESS;
}


//找到TS包头
static CSTS_Error_Code TS_iFindTSHead(u8* u8TSBuffer, int dwTSBufferLen, int* dwTSHeadPos)
{
    int i = 0;
    int j = 0;
    CSTS_BOOL bFindHeadPos = CSTS_TRUE;

    if (NULL == u8TSBuffer || NULL == dwTSHeadPos || 0 > dwTSBufferLen)
    {
        //参数错误
        return CSTS_ERROR_BAD_PARAMETER;
    }

    for (i = 0; i < dwTSBufferLen; i++)
    {

        //判断188
        for (j = 0; j < TS_CHECK_LOOP_NUM; j++)
        {
            if( (i + j*188) < dwTSBufferLen && SYNC_BYTE == u8TSBuffer[i + j*188])
            {
                bFindHeadPos = CSTS_TRUE;
                continue;
            }
            else
            {
                bFindHeadPos = CSTS_FALSE;
                break;
            }
        }
        if(bFindHeadPos)
        {
            *dwTSHeadPos = i;
            u8TSPackageLen = 188;
#if PARSE_DEBUG
            printf("包头的有效位置为:%d\n", *dwTSHeadPos);
#endif
            return CSTS_SUCCESS;
        }
    }

    //未找到188
    bFindHeadPos = CSTS_TRUE;
    for (i = 0; i < dwTSBufferLen; i++)
    {

        //判断204
        for (j = 0; j < TS_CHECK_LOOP_NUM; j++)
        {
            if( (i + j*204) < dwTSBufferLen && SYNC_BYTE == u8TSBuffer[i + j*204])
            {
                bFindHeadPos = CSTS_TRUE;
                continue;
            }
            else
            {
                bFindHeadPos = CSTS_FALSE;
                break;
            }
        }
        if(bFindHeadPos)
        {
            *dwTSHeadPos = i;
            u8TSPackageLen = 204;
#if PARSE_DEBUG
            printf("包头的有效位置为:%d\n", *dwTSHeadPos);
#endif
            return CSTS_SUCCESS;
        }
    }
    //说明188和204
    if(bFindHeadPos)
    {
        return CSTS_ERROR_TSHEAD_NOTFIND_ERROR;
    }
}

//解析头部
static CSTS_Error_Code TS_iParseHeader(TSHeader_S *pstTSHeader, u8 *pu8TSBuffer)
{
    if (NULL == pstTSHeader || NULL == pu8TSBuffer)
    {
        return CSTS_ERROR_BAD_PARAMETER;
    }

    //组装头部
    pstTSHeader->u8payload_unit_start_indicator = pu8TSBuffer[1] >> 6 & 0x01;
    pstTSHeader->wPID = (pu8TSBuffer[1] & 0x1f)<<8 | pu8TSBuffer[2];
    pstTSHeader->u8adaptation_field_control = pu8TSBuffer[3] >> 4 & 0x03;
    pstTSHeader->u8continuity_counter = pu8TSBuffer[3] & 0x03;

    return CSTS_SUCCESS;
}

static CSTS_Error_Code TS_iParseVailData(TSPackage_S* pstTSPackage, u8 *u8OneTSBuffer, int nTSPackageLen)
{
    u8* pu8VailDataBuffer = NULL;
    TSHeader_S* pstTSHeader = pstTSPackage->pstTSHeader;
    u8 u8adaptation_field_control = pstTSHeader->u8adaptation_field_control;

    int nVailDataStartPos = -1;
    int nVailDataLen = 0;


    switch(u8adaptation_field_control)
    {
        case 0:
            //丢弃
            break;
        case 1:
            nVailDataStartPos = 4;
            break;
        case 2:
            //丢弃
            break;
        case 3:
            //头部之后 有 point_field 占一个字节
            nVailDataStartPos = 4 + 1;
            nVailDataStartPos += u8OneTSBuffer[4];
            break;
    }
    if(-1 == nVailDataStartPos)
    {
        pstTSPackage->wTSBufferLen = 0;

        pstTSPackage->pu8TSBuffer = NULL;
    }

    if (1 == pstTSHeader->u8payload_unit_start_indicator)
    {
        nVailDataStartPos = nVailDataStartPos + u8OneTSBuffer[nVailDataStartPos] +1;
    }

    nVailDataLen = 188 - nVailDataStartPos;

    pu8VailDataBuffer = (u8*)malloc(nVailDataLen*sizeof(u8));

    memcpy(pu8VailDataBuffer, &u8OneTSBuffer[nVailDataStartPos], nVailDataLen);

    pstTSPackage->wTSBufferLen = nVailDataLen;

    pstTSPackage->pu8TSBuffer = pu8VailDataBuffer;

    return CSTS_SUCCESS;
}


static CSTS_Error_Code TS_iGetVailPack(int fd)
{
    u8 *u8OneTSBuffer = NULL;
    int nTSPackageLen = u8TSPackageLen;
    CSTS_Error_Code eErrCode = CSTS_ERROR_BAD_PARAMETER;
    TSHeader_S* pstTSHeader = NULL;
    TSPackage_S* pstTSPackage = NULL;
    char saaa[10];

    while(1)
    {
        u8OneTSBuffer = (u8*)malloc(nTSPackageLen*sizeof(u8));
        if(NULL == u8OneTSBuffer)
        {
            return CSTS_ERROR_NO_MEMORY;
        }

        eErrCode = TS_iFileRead(fd, u8OneTSBuffer, &nTSPackageLen);
        if(CSTS_SUCCESS != eErrCode)
        {
            return CSTS_ERROR_FILE_READ_ERROR;
        }

        pstTSHeader = (TSHeader_S*)malloc(sizeof(TSHeader_S));
        if(NULL == pstTSHeader)
        {
            return CSTS_ERROR_NO_MEMORY;
        }

        pstTSPackage = (TSPackage_S*)malloc(sizeof(TSPackage_S));
        if(NULL == pstTSPackage)
        {
            return CSTS_ERROR_NO_MEMORY;
        }

        eErrCode = TS_iParseHeader(pstTSHeader, u8OneTSBuffer);
        if(CSTS_SUCCESS != eErrCode)
        {
            return CSTS_ERROR_UNKNOWN_ERROR;
        }

        pstTSPackage->pstTSHeader = pstTSHeader;

        eErrCode = TS_iParseVailData(pstTSPackage, u8OneTSBuffer, nTSPackageLen);
        if(CSTS_SUCCESS != eErrCode) {
            return CSTS_ERROR_UNKNOWN_ERROR;
        }

        printf("---table_id = %#x ----\n",pstTSPackage->pu8TSBuffer[0]);

        /*
        tsData = TSAdjustData(&pstTSHeader_S, u8OneTSBuffer, tsPacket);

        tsPacket.pstTsHeader = &psTsHeader_S;
        tsPacket.pstTsHeader = tsData;

        if(psTsHeader_S->unPID == 0x00)
        {
            if(psTsHeader_S->unpayload_unit_start_indicator != 1)
            {
                goto A;
            }
            else
            {
                //section的第一个包
                memcpy(sectionBuffer,tsData,);


                while(1)
                {
                    result = read(fd, buff, 188);

                    TSAdjustHeader(&psTsHeader_S, buff);

                    tsData = TSAdjustData(&psTsHeader_S, buff);

                    if(psTsHeader_S->unPID == 0x00)
                    {
                        if(psTsHeader_S->unpayload_unit_start_indicator == 1)
                    }else
                    {
                        continue;
                    }
                }
            }
        }
        else
        {
            //不要
        }

        */
        printf("----%#x----\n",pstTSHeader->wPID);
        printf("----%#x----\n",pstTSHeader->u8payload_unit_start_indicator);



        //printf("----%#x----\n",pstTSHeader->u8adaptation_field_control);
        //printf("----%#x----\n",pstTSHeader->u8continuity_counter);

        //gets(saaa);
    }
}


//解析TS包
CSTS_Error_Code TSPPackageParse(char* n8TSFileName)
{
    int dwTSHeadPos = -1;
    int fd = -1;
    CSTS_Error_Code eErrCode = CSTS_ERROR_BAD_PARAMETER;
    int nPackHeadBufLen = 300*TS_CHECK_LOOP_NUM;
    u8 au8PackHeadBuf[300*TS_CHECK_LOOP_NUM] = {0};

    if(NULL == n8TSFileName)
    {
        return eErrCode;
    }

    fd  = TS_iFileOpen(n8TSFileName);
    if(-1 == fd)
    {
        return CSTS_ERROR_FILE_OPEN_ERROR;
    }

    eErrCode = TS_iFileRead(fd, au8PackHeadBuf, &nPackHeadBufLen);
    if(CSTS_SUCCESS != eErrCode)
    {
        return CSTS_ERROR_FILE_READ_ERROR;
    }

    eErrCode = TS_iFindTSHead(au8PackHeadBuf, nPackHeadBufLen, &dwTSHeadPos);
#ifdef PARSE_DEBUG
    printf("the effictive ts pos = %d\n",dwTSHeadPos);
#endif

    lseek(fd, dwTSHeadPos, SEEK_SET);

    TS_iGetVailPack(fd);
}


int main()
{
    /*
    u8 buf[1880] = {0};
    u32 dwTSHeadPos = -1;
    int fd = TS_iFileOpen("./Greendot_TS1_2.ts");
    TS_iFileRead(fd, buf, 1880);
    TS_iFindTSHead(buf, 1880, &dwTSHeadPos);

    lseek(fd, i, SEEK_SET);

    while(1)
    {
        TS_iFileRead(fd, buf, );
        if()
    }

    return 0;
    */

    TSPPackageParse("./Greendot_TS1_2.ts");
    return 0;
}

